package com.nb.dp.strategy.v2;

import com.nb.dp.strategy.v1.PayStrategy;
import org.springframework.aop.support.AopUtils;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.stereotype.Component;

import java.util.Map;

/**
 * ApplicationContextAware接口的setApplicationContext()方法是在Spring容器初始化你的bean之后，
 * 在任何初始化回调（如InitializingBean的afterPropertiesSet或@PostConstruct注解的方法）之前调用的。
 * 这是因为ApplicationContextAware接口的setApplicationContext()方法是由Spring容器在
 * ApplicationContextAwareProcessor中处理的，这个处理器是在AbstractApplicationContext的
 * invokeBeanFactoryPostProcessors()方法中被调用的，而这个方法是在容器的刷新流程refresh()中的
 * prepareBeanFactory()方法之后，postProcessBeanFactory()方法之前调用的。
 * 所以，ApplicationContextAware的setApplicationContext()方法的调用时机是在bean的属性填充之后，
 * 初始化回调之前。这样，你的bean在执行初始化回调时，就可以使用ApplicationContext了。
 * @author lihaoyang6
 * @date 2023年11月30日 17:39
 */
@Component
public class PayFactoryByAware implements ApplicationContextAware { //实现ApplicationContextAware接口也可以


    @Autowired
    private Map<String, PayStrategy> payStrategyMap;


    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        Map<String, PayStrategy> beansOfType = applicationContext.getBeansOfType(PayStrategy.class);
        for (PayStrategy value : beansOfType.values()) {
            Class<?> targetClass = AopUtils.getTargetClass(value);
            PayType annotation = targetClass.getAnnotation(PayType.class);
            if (annotation != null) {
                payStrategyMap.put(annotation.value(), value);
            }
        }
        System.out.println("xxxxxxxxxxxxx");
    }





    public PayStrategy getPayStrategy(String payType){
        PayStrategy payStrategy = payStrategyMap.get(payType);
        if(payStrategy == null) {throw new NullPointerException("未找到类型为【"+payType+"】的支付方式实现类");}
        return payStrategy;
    }



}
